logging 模块 -> 一般是用于输出日志和保存日志
日志级别等级: critical > error > warning > info > debug
一般情况下只会输出 warning 级别以上的错误信息,如果想输出 warning 级别以下的信息可以通过 basicConfig 和 logger 进行配置输出
debug | 测试信息 | 记录测试代码的数据 |
info | 正常信息 | 记录正常的操作信息 |
warning | 警告信息 | 记录不影响程序运行,但是会出现一下小问题的信息 例如: while True input且用户输入的信息不对无法进入程序,这时就可给出警告信息 |
error | 错误信息 | 记录程序运行时进入了 try expert 里面的错误信息 |
critical | 严重错误信息 | 记录系统级别的错误 |
import logging
logging.debug('debug message') # 测试信息 -> 记录测试代码的数据
logging.info('info message') # 正常信息 -> 记录正常的操作信息
logging.warning('warning message') # 警告信息 -> 记录不影响程序运行,但是会出现一下小问题的信息,例如: while True input且用户输入的信息不对无法进入程序,这时就可给出警告信息
logging.error('error message') # 错误信息 -> 记录程序运行时进入了 try expert 里面的错误信息
logging.critical('critical message') # 严重错误信息 -> 系统级别的错误
1. basicConfig
- 配置日志的输入格式 和 输出位置
- 缺点: 输出中文会乱码 / 不能同时往控制台和文件输出 / 不能将错误信息分别输出到不同的日志文件
import logging
logging.basicConfig(
level=logging.DEBUG, # 输出xxx级别以上的错误信息
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', # 日志信息的输出格式
datefmt='%Y-%m-%d %H:%M:%S', # 时间格式
filename='log.log', # 日志保存的文件路径,如果没有该项默认输出到控制台
filemode='w' # 以什么形式打开文件
)
try:
int(input('num >>'))
except ValueError:
logging.error('输入的值不是一个数字')
logging.debug('debug message') # 测试信息
logging.info('info message') # 正常信息
logging.warning('warning message') # 警告信息
logging.error('error message') # 错误信息
logging.critical('critical message') # 严重错误信息
- basicConfig的参数
level=logging.DEBUG | 指定输出xxx级别以上的错误信息 |
format | 指定日志信息的输出格式 |
datefmt | 指定时间格式 |
filename | 日志保存的文件路径,如果没有该项默认输出到控制台 |
filemode | 指定以什么形式打开文件 |
- format参数中可能会用到的格式化串
%(name)s | Logger的名字 |
%(levelno)s | 数字形式的日志级别 |
%(levelname)s | 文本形式的日志级别 |
%(pathname)s | 调用日志输出函数的模块的完整路径名,可能没有 |
%(filename)s | 调用日志输出函数的模块的文件名 |
%(module)s | 调用日志输出函数的模块名 |
%(funcName)s | 调用日志输出函数的函数名 |
%(lineno)d | 调用日志输出函数的语句所在的代码行 |
%(created)f | 当前时间,用UNIX标准的表示时间的浮 点数表示 |
%(relativeCreated)d | 输出日志信息时的,自Logger创建以 来的毫秒数 |
%(asctime)s | 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
%(thread)d | 线程ID。可能没有 |
%(threadName)s | 线程名。可能没有 |
%(process)d | 进程ID。可能没有 |
%(message)s | 用户输出的消息 |
2. logger -> 推荐使用
- 配置日志的输入格式 和 输出位置
- 可以输出中文
- 可以同时输出到控制台和文件
- 可以将错误信息分别输出到不同的日志文件
import logging
logger = logging.getLogger()
# logger = logging.getLogger(__name__) # 生成一个以当前文件名为名字的logger实例 -> 一般用于Django的日志中
# collect_logger = logging.getLogger("collect") # 生成一个名为collect的logger实例 -> 一般用于Django的日志中
logger.setLevel(logging.DEBUG) # 设置文件和控制台指定输出xxx级别以上的错误信息,如果没有这个设置,下面使用 fh.setLevel 或 sh.setLevel 会无效
fh = logging.FileHandler('log.log', 'w', encoding='utf-8') # 创建一个文件操作符,用于将日志保存到该日志文件中 -> 文件默认以追加的形式打开
sh = logging.StreamHandler() # 创建一个控制台对象,用于将日志显示到控制台
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 日志的输出格式
formatter2 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s [line:%(lineno)d] : %(message)s') # 日志的输出格式
fh.setLevel(logging.INFO) # 指定输出xxx级别以上的错误信息
sh.setLevel(logging.ERROR) # 指定输出xxx级别以上的错误信息
fh.setFormatter(formatter) # 文件操作符 和 日志输出格式关联
sh.setFormatter(formatter2) # 控制台对象 和 日志输出格式关联
logger.addHandler(fh) # logger对象 和 文件操作符关联
logger.addHandler(sh) # logger对象 和 控制台对象关联
# ——————————————————————————————————————————————————————————————
try:
int(input('num >>'))
except ValueError:
logging.error('输入的值不是一个数字')
logging.debug('debug message') # 测试信息
logging.info('info message') # 正常信息
logging.warning('warning message') # 警告信息
logging.error('error message') # 错误信息
logging.critical('critical message') # 严重错误信息
3. 获取字符串类型的控制台所打印出来的错误信息
import traceback
try:
a = a + 1
except Exception as e:
msg = traceback.format_exc() # 获取字符串类型的控制台所打印出来的错误信息
print(msg)
"""
msg 所打印出来的内容:
Traceback (most recent call last):
File "C:/Users/Mr. Yeung/Desktop/test/test.py", line 4, in <module>
a = a + 1
NameError: name 'a' is not defined
"""
4. 什么时候需要写日志
- 当出现了异常并且被捕获到的时候
- 日志的作用: 记录错误或有用的信息,方便排查错误和对有用的信息进行处理
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # 设置文件和控制台指定输出xxx级别以上的错误信息,如果没有这个设置,下面使用 fh.setLevel 或 sh.setLevel 会无效
fh = logging.FileHandler('log.log', 'w', encoding='utf-8') # 创建一个文件操作符,用于将日志保存到该日志文件中 -> 文件默认以追加的形式打开
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s [line:%(lineno)d] : %(message)s') # 日志的输出格式
fh.setLevel(logging.INFO) # 指定输出xxx级别以上的错误信息
fh.setFormatter(formatter) # 文件操作符 和 日志输出格式关联
logger.addHandler(fh) # logger对象 和 文件操作符关联
# ——————————————————————————————————————————————————————————————
try:
int(input('num >>'))
except ValueError as e:
logging.error(str(e))